//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension Billing {
    // MARK: Enums

    public enum BillingViewStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case creating = "CREATING"
        case healthy = "HEALTHY"
        case unhealthy = "UNHEALTHY"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum BillingViewStatusReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case aggregateSource = "AGGREGATE_SOURCE"
        case cyclicDependency = "CYCLIC_DEPENDENCY"
        case sourceViewAccessDenied = "SOURCE_VIEW_ACCESS_DENIED"
        case sourceViewDepthExceeded = "SOURCE_VIEW_DEPTH_EXCEEDED"
        case sourceViewNotFound = "SOURCE_VIEW_NOT_FOUND"
        case sourceViewUnhealthy = "SOURCE_VIEW_UNHEALTHY"
        case sourceViewUpdating = "SOURCE_VIEW_UPDATING"
        case viewOwnerNotManagementAccount = "VIEW_OWNER_NOT_MANAGEMENT_ACCOUNT"
        public var description: String { return self.rawValue }
    }

    public enum BillingViewType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case billingGroup = "BILLING_GROUP"
        case custom = "CUSTOM"
        case primary = "PRIMARY"
        public var description: String { return self.rawValue }
    }

    public enum Dimension: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case linkedAccount = "LINKED_ACCOUNT"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "cannotParse"
        case fieldValidationFailed = "fieldValidationFailed"
        case other = "other"
        case unknownOperation = "unknownOperation"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ActiveTimeRange: AWSEncodableShape {
        /// The inclusive time range start date.
        public let activeAfterInclusive: Date
        ///  The inclusive time range end date.
        public let activeBeforeInclusive: Date

        @inlinable
        public init(activeAfterInclusive: Date, activeBeforeInclusive: Date) {
            self.activeAfterInclusive = activeAfterInclusive
            self.activeBeforeInclusive = activeBeforeInclusive
        }

        private enum CodingKeys: String, CodingKey {
            case activeAfterInclusive = "activeAfterInclusive"
            case activeBeforeInclusive = "activeBeforeInclusive"
        }
    }

    public struct AssociateSourceViewsRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) of the billing view to associate source views with.
        public let arn: String
        ///  A list of ARNs of the source billing views to associate.
        public let sourceViews: [String]

        @inlinable
        public init(arn: String, sourceViews: [String]) {
            self.arn = arn
            self.sourceViews = sourceViews
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            try self.sourceViews.forEach {
                try validate($0, name: "sourceViews[]", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            }
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, max: 10)
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case sourceViews = "sourceViews"
        }
    }

    public struct AssociateSourceViewsResponse: AWSDecodableShape {
        ///  The ARN of the billing view that the source views were associated with.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct BillingViewElement: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String?
        /// The type of billing group.
        public let billingViewType: BillingViewType?
        /// The time when the billing view was created.
        public let createdAt: Date?
        ///  See Expression. Billing view only supports LINKED_ACCOUNT and Tags.
        public let dataFilterExpression: Expression?
        ///  The number of billing views that use this billing view as a source.
        public let derivedViewCount: Int?
        ///  The description of the billing view.
        public let description: String?
        ///  The current health status of the billing view.
        public let healthStatus: BillingViewHealthStatus?
        ///  The account name of the billing view.
        public let name: String?
        /// The account owner of the billing view.
        public let ownerAccountId: String?
        ///  The Amazon Web Services account ID that owns the source billing view, if this is a derived billing view.
        public let sourceAccountId: String?
        ///  The number of source views associated with this billing view.
        public let sourceViewCount: Int?
        /// The time when the billing view was last updated.
        public let updatedAt: Date?
        ///  The timestamp of when the billing view definition was last updated.
        public let viewDefinitionLastUpdatedAt: Date?

        @inlinable
        public init(arn: String? = nil, billingViewType: BillingViewType? = nil, createdAt: Date? = nil, dataFilterExpression: Expression? = nil, derivedViewCount: Int? = nil, description: String? = nil, healthStatus: BillingViewHealthStatus? = nil, name: String? = nil, ownerAccountId: String? = nil, sourceAccountId: String? = nil, sourceViewCount: Int? = nil, updatedAt: Date? = nil, viewDefinitionLastUpdatedAt: Date? = nil) {
            self.arn = arn
            self.billingViewType = billingViewType
            self.createdAt = createdAt
            self.dataFilterExpression = dataFilterExpression
            self.derivedViewCount = derivedViewCount
            self.description = description
            self.healthStatus = healthStatus
            self.name = name
            self.ownerAccountId = ownerAccountId
            self.sourceAccountId = sourceAccountId
            self.sourceViewCount = sourceViewCount
            self.updatedAt = updatedAt
            self.viewDefinitionLastUpdatedAt = viewDefinitionLastUpdatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case billingViewType = "billingViewType"
            case createdAt = "createdAt"
            case dataFilterExpression = "dataFilterExpression"
            case derivedViewCount = "derivedViewCount"
            case description = "description"
            case healthStatus = "healthStatus"
            case name = "name"
            case ownerAccountId = "ownerAccountId"
            case sourceAccountId = "sourceAccountId"
            case sourceViewCount = "sourceViewCount"
            case updatedAt = "updatedAt"
            case viewDefinitionLastUpdatedAt = "viewDefinitionLastUpdatedAt"
        }
    }

    public struct BillingViewHealthStatus: AWSDecodableShape {
        /// The current health status code of the billing view.
        public let statusCode: BillingViewStatus?
        /// A list of reasons explaining the current health status, if applicable.
        public let statusReasons: [BillingViewStatusReason]?

        @inlinable
        public init(statusCode: BillingViewStatus? = nil, statusReasons: [BillingViewStatusReason]? = nil) {
            self.statusCode = statusCode
            self.statusReasons = statusReasons
        }

        private enum CodingKeys: String, CodingKey {
            case statusCode = "statusCode"
            case statusReasons = "statusReasons"
        }
    }

    public struct BillingViewListElement: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String?
        /// The type of billing view.
        public let billingViewType: BillingViewType?
        ///  The description of the billing view.
        public let description: String?
        ///  The current health status of the billing view.
        public let healthStatus: BillingViewHealthStatus?
        ///  A list of names of the Billing view.
        public let name: String?
        ///  The list of owners of the Billing view.
        public let ownerAccountId: String?
        ///  The Amazon Web Services account ID that owns the source billing view, if this is a derived billing view.
        public let sourceAccountId: String?

        @inlinable
        public init(arn: String? = nil, billingViewType: BillingViewType? = nil, description: String? = nil, healthStatus: BillingViewHealthStatus? = nil, name: String? = nil, ownerAccountId: String? = nil, sourceAccountId: String? = nil) {
            self.arn = arn
            self.billingViewType = billingViewType
            self.description = description
            self.healthStatus = healthStatus
            self.name = name
            self.ownerAccountId = ownerAccountId
            self.sourceAccountId = sourceAccountId
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case billingViewType = "billingViewType"
            case description = "description"
            case healthStatus = "healthStatus"
            case name = "name"
            case ownerAccountId = "ownerAccountId"
            case sourceAccountId = "sourceAccountId"
        }
    }

    public struct ConflictException: AWSErrorShape {
        public let message: String
        ///  The identifier for the service resource associated with the request.
        public let resourceId: String
        ///  The type of resource associated with the request.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct CreateBillingViewRequest: AWSEncodableShape {
        /// A unique, case-sensitive identifier you specify to ensure idempotency of the request. Idempotency ensures that an API request completes no more than one time. If the original request completes successfully, any subsequent retries complete successfully without performing any further actions with an idempotent request.
        public let clientToken: String?
        ///  See Expression. Billing view only supports LINKED_ACCOUNT and Tags.
        public let dataFilterExpression: Expression?
        ///  The description of the billing view.
        public let description: String?
        ///  The name of the billing view.
        public let name: String
        /// A list of key value map specifying tags associated to the billing view being created.
        public let resourceTags: [ResourceTag]?
        /// A list of billing views used as the data source for the custom billing view.
        public let sourceViews: [String]

        @inlinable
        public init(clientToken: String? = CreateBillingViewRequest.idempotencyToken(), dataFilterExpression: Expression? = nil, description: String? = nil, name: String, resourceTags: [ResourceTag]? = nil, sourceViews: [String]) {
            self.clientToken = clientToken
            self.dataFilterExpression = dataFilterExpression
            self.description = description
            self.name = name
            self.resourceTags = resourceTags
            self.sourceViews = sourceViews
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeHeader(self.clientToken, key: "X-Amzn-Client-Token")
            try container.encodeIfPresent(self.dataFilterExpression, forKey: .dataFilterExpression)
            try container.encodeIfPresent(self.description, forKey: .description)
            try container.encode(self.name, forKey: .name)
            try container.encodeIfPresent(self.resourceTags, forKey: .resourceTags)
            try container.encode(self.sourceViews, forKey: .sourceViews)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.dataFilterExpression?.validate(name: "\(name).dataFilterExpression")
            try self.validate(self.description, name: "description", parent: name, max: 1024)
            try self.validate(self.description, name: "description", parent: name, pattern: "^([ a-zA-Z0-9_\\+=\\.\\-@]+)?$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9_\\+=\\.\\-@]+$")
            try self.resourceTags?.forEach {
                try $0.validate(name: "\(name).resourceTags[]")
            }
            try self.validate(self.resourceTags, name: "resourceTags", parent: name, max: 200)
            try self.sourceViews.forEach {
                try validate($0, name: "sourceViews[]", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            }
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, max: 10)
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case dataFilterExpression = "dataFilterExpression"
            case description = "description"
            case name = "name"
            case resourceTags = "resourceTags"
            case sourceViews = "sourceViews"
        }
    }

    public struct CreateBillingViewResponse: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String
        ///  The time when the billing view was created.
        public let createdAt: Date?

        @inlinable
        public init(arn: String, createdAt: Date? = nil) {
            self.arn = arn
            self.createdAt = createdAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createdAt = "createdAt"
        }
    }

    public struct DeleteBillingViewRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String
        ///  If set to true, forces deletion of the billing view even if it has derived resources (e.g. other billing views or budgets). Use with caution as this may break dependent resources.
        public let force: Bool?

        @inlinable
        public init(arn: String, force: Bool? = nil) {
            self.arn = arn
            self.force = force
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case force = "force"
        }
    }

    public struct DeleteBillingViewResponse: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DimensionValues: AWSEncodableShape & AWSDecodableShape {
        ///  The names of the metadata types that you can use to filter and group your results.
        public let key: Dimension
        ///  The metadata values that you can use to filter and group your results.
        public let values: [String]

        @inlinable
        public init(key: Dimension, values: [String]) {
            self.key = key
            self.values = values
        }

        public func validate(name: String) throws {
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, max: 1024)
                try validate($0, name: "values[]", parent: name, pattern: "^[\\S\\s]*$")
            }
            try self.validate(self.values, name: "values", parent: name, max: 200)
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "key"
            case values = "values"
        }
    }

    public struct DisassociateSourceViewsRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) of the billing view to disassociate source views from.
        public let arn: String
        ///  A list of ARNs of the source billing views to disassociate.
        public let sourceViews: [String]

        @inlinable
        public init(arn: String, sourceViews: [String]) {
            self.arn = arn
            self.sourceViews = sourceViews
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            try self.sourceViews.forEach {
                try validate($0, name: "sourceViews[]", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            }
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, max: 10)
            try self.validate(self.sourceViews, name: "sourceViews", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case sourceViews = "sourceViews"
        }
    }

    public struct DisassociateSourceViewsResponse: AWSDecodableShape {
        ///  The ARN of the billing view that the source views were disassociated from.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct Expression: AWSEncodableShape & AWSDecodableShape {
        ///  The specific Dimension to use for Expression.
        public let dimensions: DimensionValues?
        ///  The specific Tag to use for Expression.
        public let tags: TagValues?
        ///  Specifies a time range filter for the billing view data.
        public let timeRange: TimeRange?

        @inlinable
        public init(dimensions: DimensionValues? = nil, tags: TagValues? = nil, timeRange: TimeRange? = nil) {
            self.dimensions = dimensions
            self.tags = tags
            self.timeRange = timeRange
        }

        public func validate(name: String) throws {
            try self.dimensions?.validate(name: "\(name).dimensions")
            try self.tags?.validate(name: "\(name).tags")
        }

        private enum CodingKeys: String, CodingKey {
            case dimensions = "dimensions"
            case tags = "tags"
            case timeRange = "timeRange"
        }
    }

    public struct GetBillingViewRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetBillingViewResponse: AWSDecodableShape {
        /// The billing view element associated with the specified ARN.
        public let billingView: BillingViewElement

        @inlinable
        public init(billingView: BillingViewElement) {
            self.billingView = billingView
        }

        private enum CodingKeys: String, CodingKey {
            case billingView = "billingView"
        }
    }

    public struct GetResourcePolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the billing view resource to which the policy is attached to.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:[a-zA-Z0-9/:_\\+=\\.\\@-]{0,70}[a-zA-Z0-9]$")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
        }
    }

    public struct GetResourcePolicyResponse: AWSDecodableShape {
        /// The resource-based policy document attached to the resource in JSON format.
        public let policy: String?
        /// The Amazon Resource Name (ARN) of the billing view resource to which the policy is attached to.
        public let resourceArn: String

        @inlinable
        public init(policy: String? = nil, resourceArn: String) {
            self.policy = policy
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "policy"
            case resourceArn = "resourceArn"
        }
    }

    public struct ListBillingViewsRequest: AWSEncodableShape {
        ///  The time range for the billing views listed. PRIMARY billing view is always listed. BILLING_GROUP billing views are listed for time ranges when the associated billing group resource in Billing Conductor is active. The time range must be within one calendar month.
        public let activeTimeRange: ActiveTimeRange?
        /// The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arns: [String]?
        /// The type of billing view.
        public let billingViewTypes: [BillingViewType]?
        /// The maximum number of billing views to retrieve. Default is 100.
        public let maxResults: Int?
        /// The pagination token that is used on subsequent calls to list billing views.
        public let nextToken: String?
        ///  The list of owners of the billing view.
        public let ownerAccountId: String?
        ///  Filters the results to include only billing views that use the specified account as a source.
        public let sourceAccountId: String?

        @inlinable
        public init(activeTimeRange: ActiveTimeRange? = nil, arns: [String]? = nil, billingViewTypes: [BillingViewType]? = nil, maxResults: Int? = nil, nextToken: String? = nil, ownerAccountId: String? = nil, sourceAccountId: String? = nil) {
            self.activeTimeRange = activeTimeRange
            self.arns = arns
            self.billingViewTypes = billingViewTypes
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.ownerAccountId = ownerAccountId
            self.sourceAccountId = sourceAccountId
        }

        public func validate(name: String) throws {
            try self.arns?.forEach {
                try validate($0, name: "arns[]", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            }
            try self.validate(self.arns, name: "arns", parent: name, max: 10)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2047)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.ownerAccountId, name: "ownerAccountId", parent: name, pattern: "^[0-9]{12}$")
            try self.validate(self.sourceAccountId, name: "sourceAccountId", parent: name, pattern: "^[0-9]{12}$")
        }

        private enum CodingKeys: String, CodingKey {
            case activeTimeRange = "activeTimeRange"
            case arns = "arns"
            case billingViewTypes = "billingViewTypes"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
            case ownerAccountId = "ownerAccountId"
            case sourceAccountId = "sourceAccountId"
        }
    }

    public struct ListBillingViewsResponse: AWSDecodableShape {
        /// A list of BillingViewListElement retrieved.
        public let billingViews: [BillingViewListElement]
        /// The pagination token to use on subsequent calls to list billing views.
        public let nextToken: String?

        @inlinable
        public init(billingViews: [BillingViewListElement], nextToken: String? = nil) {
            self.billingViews = billingViews
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case billingViews = "billingViews"
            case nextToken = "nextToken"
        }
    }

    public struct ListSourceViewsForBillingViewRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String
        ///  The number of entries a paginated response contains.
        public let maxResults: Int?
        ///  The pagination token that is used on subsequent calls to list billing views.
        public let nextToken: String?

        @inlinable
        public init(arn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.arn = arn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2047)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListSourceViewsForBillingViewResponse: AWSDecodableShape {
        ///  The pagination token that is used on subsequent calls to list billing views.
        public let nextToken: String?
        /// A list of billing views used as the data source for the custom billing view.
        public let sourceViews: [String]

        @inlinable
        public init(nextToken: String? = nil, sourceViews: [String]) {
            self.nextToken = nextToken
            self.sourceViews = sourceViews
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case sourceViews = "sourceViews"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:[a-zA-Z0-9/:_\\+=\\.\\@-]{0,70}[a-zA-Z0-9]$")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        ///  A list of tag key value pairs that are associated with the resource.
        public let resourceTags: [ResourceTag]?

        @inlinable
        public init(resourceTags: [ResourceTag]? = nil) {
            self.resourceTags = resourceTags
        }

        private enum CodingKeys: String, CodingKey {
            case resourceTags = "resourceTags"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        public let message: String
        ///  Value is a list of resource IDs that were not found.
        public let resourceId: String
        ///  Value is the type of resource that was not found.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct ResourceTag: AWSEncodableShape & AWSDecodableShape {
        ///  The key that's associated with the tag.
        public let key: String
        ///  The value that's associated with the tag.
        public let value: String?

        @inlinable
        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "key"
            case value = "value"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        public let message: String
        ///  The container for the quotaCode.
        public let quotaCode: String
        ///  The ID of the resource.
        public let resourceId: String
        ///  The type of Amazon Web Services resource.
        public let resourceType: String
        ///  The container for the serviceCode.
        public let serviceCode: String

        @inlinable
        public init(message: String, quotaCode: String, resourceId: String, resourceType: String, serviceCode: String) {
            self.message = message
            self.quotaCode = quotaCode
            self.resourceId = resourceId
            self.resourceType = resourceType
            self.serviceCode = serviceCode
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
            case serviceCode = "serviceCode"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        ///  A list of tag key value pairs that are associated with the resource.
        public let resourceTags: [ResourceTag]

        @inlinable
        public init(resourceArn: String, resourceTags: [ResourceTag]) {
            self.resourceArn = resourceArn
            self.resourceTags = resourceTags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:[a-zA-Z0-9/:_\\+=\\.\\@-]{0,70}[a-zA-Z0-9]$")
            try self.resourceTags.forEach {
                try $0.validate(name: "\(name).resourceTags[]")
            }
            try self.validate(self.resourceTags, name: "resourceTags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
            case resourceTags = "resourceTags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct TagValues: AWSEncodableShape & AWSDecodableShape {
        ///  The key for the tag.
        public let key: String
        ///  The specific value of the tag.
        public let values: [String]

        @inlinable
        public init(key: String, values: [String]) {
            self.key = key
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 1024)
            try self.validate(self.key, name: "key", parent: name, pattern: "^[\\S\\s]*$")
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, max: 1024)
                try validate($0, name: "values[]", parent: name, pattern: "^[\\S\\s]*$")
            }
            try self.validate(self.values, name: "values", parent: name, max: 200)
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "key"
            case values = "values"
        }
    }

    public struct TimeRange: AWSEncodableShape & AWSDecodableShape {
        ///  The inclusive start date of the time range.
        public let beginDateInclusive: Date?
        ///  The inclusive end date of the time range.
        public let endDateInclusive: Date?

        @inlinable
        public init(beginDateInclusive: Date? = nil, endDateInclusive: Date? = nil) {
            self.beginDateInclusive = beginDateInclusive
            self.endDateInclusive = endDateInclusive
        }

        private enum CodingKeys: String, CodingKey {
            case beginDateInclusive = "beginDateInclusive"
            case endDateInclusive = "endDateInclusive"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        ///  A list of tag key value pairs that are associated with the resource.
        public let resourceTagKeys: [String]

        @inlinable
        public init(resourceArn: String, resourceTagKeys: [String]) {
            self.resourceArn = resourceArn
            self.resourceTagKeys = resourceTagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:[a-zA-Z0-9/:_\\+=\\.\\@-]{0,70}[a-zA-Z0-9]$")
            try self.resourceTagKeys.forEach {
                try validate($0, name: "resourceTagKeys[]", parent: name, max: 128)
                try validate($0, name: "resourceTagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.resourceTagKeys, name: "resourceTagKeys", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
            case resourceTagKeys = "resourceTagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateBillingViewRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String
        /// See Expression. Billing view only supports LINKED_ACCOUNT and Tags.
        public let dataFilterExpression: Expression?
        ///  The description of the billing view.
        public let description: String?
        ///  The name of the billing view.
        public let name: String?

        @inlinable
        public init(arn: String, dataFilterExpression: Expression? = nil, description: String? = nil, name: String? = nil) {
            self.arn = arn
            self.dataFilterExpression = dataFilterExpression
            self.description = description
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws[a-z-]*:(billing)::[0-9]{12}:billingview/[a-zA-Z0-9/:_\\+=\\.\\-@]{0,75}[a-zA-Z0-9]$")
            try self.dataFilterExpression?.validate(name: "\(name).dataFilterExpression")
            try self.validate(self.description, name: "description", parent: name, max: 1024)
            try self.validate(self.description, name: "description", parent: name, pattern: "^([ a-zA-Z0-9_\\+=\\.\\-@]+)?$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9_\\+=\\.\\-@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case dataFilterExpression = "dataFilterExpression"
            case description = "description"
            case name = "name"
        }
    }

    public struct UpdateBillingViewResponse: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) that can be used to uniquely identify the billing view.
        public let arn: String
        ///  The time when the billing view was last updated.
        public let updatedAt: Date?

        @inlinable
        public init(arn: String, updatedAt: Date? = nil) {
            self.arn = arn
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case updatedAt = "updatedAt"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// The input fails to satisfy the constraints specified by an Amazon Web Services service.
        public let fieldList: [ValidationExceptionField]?
        public let message: String
        /// The input fails to satisfy the constraints specified by an Amazon Web Services service.
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// The message describing why the field failed validation.
        public let message: String
        /// The name of the field.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for Billing
public struct BillingErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case billingViewHealthStatusException = "BillingViewHealthStatusException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Billing
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You don't have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    ///  Exception thrown when a billing view's health status prevents an operation from being performed. This may occur if the billing view is in a state other than HEALTHY.
    public static var billingViewHealthStatusException: Self { .init(.billingViewHealthStatusException) }
    ///  The requested operation would cause a conflict with the current state of a service resource associated with the request. Resolve the conflict before retrying this request.
    public static var conflictException: Self { .init(.conflictException) }
    /// The request processing failed because of an unknown error, exception, or failure.
    public static var internalServerException: Self { .init(.internalServerException) }
    ///  The specified ARN in the request doesn't exist.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    ///  You've reached the limit of resources you can create, or exceeded the size of an individual resource.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The input fails to satisfy the constraints specified by an Amazon Web Services service.
    public static var validationException: Self { .init(.validationException) }
}

extension BillingErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": Billing.ConflictException.self,
        "ResourceNotFoundException": Billing.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": Billing.ServiceQuotaExceededException.self,
        "ValidationException": Billing.ValidationException.self
    ]
}

extension BillingErrorType: Equatable {
    public static func == (lhs: BillingErrorType, rhs: BillingErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension BillingErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
